小程序通过WebSocket控制Flutter APP进行拍照录像

前言

公司业务有个需求,为了检测某项运动项目的动作标准性,我们需要从不同的两个方向同时拍摄3s左右的视频,那么我们可能需要想办法用一台手机发送指令,控制另外两台手机进行录像。这里我们选用的技术方案是通过WebSocket。

image

image

这里拍起来不太方便,就这么凑合着看着吧,下边是录好视频的效果

思路

Dart他本身可以作为socket的服务接收client的请求,所以在每台flutter的app中(拍摄设备)启动一个socket服务,因为他们在同一局域网内,小程序可以通过ip地址来连接到flutter的socket服务,小程序可以连接最多五个个socket服务,最多可以控制五台设备。

小程序部分

先填写两台设备的ip地址(从APP里边获取ipAddress),只要在同一个局域网内,应该都能连接成功,连接成功后,获取回调socketTask,他有一系列socket的api,这里不多叙述了

1
2
3
4
5
6
7
8
9
10
11
12
13
async connectWebsocket() {
const socketTask1 = await Taro.connectSocket({
url: `ws://${this.state.ipAddress1}:4041/ws`,
})

const socketTask2 = await Taro.connectSocket({
url: `ws://${this.state.ipAddress2}:4041/ws`,
})

this.setState({
socketTask1, socketTask2
})
}

接着就能给flutter发送数据了,通过 socketTask.send(object)

1
2
3
4
5
6
7
8
9
sendMessage(e) {
this.state.socketTask1.send({
data: e.detail.value
})

this.state.socketTask2.send({
data: e.detail.value
})
}

这里我写了几个方法,直接通过socket传拍照、录像、停止录像的信息到APP的socket服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
takePhoto() {
this.state.socketTask1.send({
data: 'takephoto'
})

this.state.socketTask2.send({
data: 'takephoto'
})
}

startVideo() {
this.state.socketTask1.send({
data: 'startvideo'
})

this.state.socketTask2.send({
data: 'startvideo'
})
}

stopVideo() {
this.state.socketTask1.send({
data: 'stopvideo'
})

this.state.socketTask2.send({
data: 'stopvideo'
})
}

Flutter部分

这里我直接拷贝了网上Dart socket服务的写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//  打开WebSocket
startSocketServer() async {
try {
ipAddress = await GetIp.ipAddress;
setState(() {
this.ipAddress = ipAddress;
});

var server = await HttpServer.bind(ipAddress, 4041);
await for (HttpRequest req in server) {
if (req.uri.path == '/ws') {
// 将一个HttpRequest提升为WebSocket连接
var socket = await WebSocketTransformer.upgrade(req);
socket.listen((event) {
setState(() {
message = event;
});
print("接收到来自 ${req.connectionInfo.remoteAddress.address}:${req.connectionInfo.remotePort} 的消息:$event");

if(event == 'takephoto') {
takingPictures();
} else if (event == 'startvideo') {
onVideoRecordButtonPressed();
} else if (event == 'stopvideo') {
onStopButtonPressed();
} else {
print(event);
}

socket.add("数据已接收!");
});
}
}
} catch (e) {
print(e);
}
}

中间takingPictures()、onVideoRecordButtonPressed()、onStopButtonPressed()就是拍照、录像、停止录像的方法,至此,小程序就已成功控制了flutter进行拍照录像